import shutil
import subprocess
import tkinter as tk
import tkinter.ttk
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter.messagebox import *
import os
import os.path
import glob
import sys
import re
import openpyxl
import win32com.client as win32
import warnings
# 忽略UserWarning警告
warnings.filterwarnings("ignore", category=UserWarning)

startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# 调整为SW_HIDE,表示创建的进程窗口在显示时不会激活
startupinfo.wShowWindow = subprocess.SW_HIDE

# 取得路径
def app_path():
    if hasattr(sys, 'frozen'):  # 可执行文件走这里
        return os.path.abspath(sys.executable)
    return os.path.abspath(__file__)  # 源码走这里

# 界面作成
window = tk.Tk()
window.title("check_GTR_SRS_STR_text")
window.geometry("750x300+600+400") 

# 创建 PanedWindow
paned_window = ttk.PanedWindow(window, orient=tk.HORIZONTAL)
paned_window.pack(fill=tk.BOTH, expand=True)
# 创建左侧的 Frame 用于放置按钮
left_frame = ttk.Frame(paned_window, width=150)
paned_window.add(left_frame, weight=1)
# 创建右侧的 Frame 用于显示具体内容
right_frame = ttk.Frame(paned_window)
paned_window.add(right_frame, weight=5)
# -------------------------------------------------------------------------------------page_1-------------------------------------------------------------------------------------
# 界面参数
page_1 = ttk.Frame(right_frame)

# 文件路径
def importfile_file_select_1():
    file_path = filedialog.askopenfilename()
    import_1.config(text=file_path)
import_1 = tk.Message(page_1, width=300, text="")
import_1.place(x=20, y=70, anchor="w")
import_botton_1 = tk.Button(page_1, text="SRS file", width=15, command=importfile_file_select_1)
import_botton_1.place(x=350, y=50)

def schedule_file_select_1():
    file_path = filedialog.askopenfilename()
    schedule_1.config(text=file_path)
schedule_1 = tk.Message(page_1, width=300, text="")
schedule_1.place(x=20, y=120, anchor="w")
schedule_botton_1 = tk.Button(page_1, text="GTR file", width=15, command=schedule_file_select_1)
schedule_botton_1.place(x=350, y=100)

def on_entry_pi_in(event):
    if PI_entry.get() == "eg:PI26/PI26.1":
        PI_entry.delete(0, tk.END)  # 清空内容
        PI_entry.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out(event):
    if PI_entry.get() == "":
        PI_entry.insert(0, "eg:PI26/PI26.1")  # 插入提示字符
        PI_entry.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label = tk.Label(page_1, width=10, text="PI")
PI_label.place(x=50, y=160, anchor="w")
PI_entry = tk.Entry(page_1, width=15, fg="grey")
PI_entry.insert(0, "eg:PI26/PI26.1")  # 设置初始提示字符
PI_entry.place(x=100, y=160, anchor="w")
# 绑定事件
PI_entry.bind("<FocusIn>", on_entry_pi_in)  # 获取焦点时触发
PI_entry.bind("<FocusOut>", on_entry_pi_out)  # 失去焦点时触发

def start_1():
    datacheck_1(import_1["text"], schedule_1["text"])

start_botton_1 = tk.Button(page_1, text="开始", width=15, command=start_1)
start_botton_1.place(x=350, y=150)

def datacheck_1(srs_file, gtr_file):
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except Exception as e:
        pass

    PI_value = str(PI_entry.get()).strip()
    pattern = r'^PI\d+(\.\d)?$'
    PI_match = re.match(pattern, PI_value)
    if PI_match:
        pass
    else:
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不正确"))
        return
    
    error_list = []
    srs_data = {}
    gtr_data = {}
    # 启动Excel应用
    excel = win32.gencache.EnsureDispatch('Excel.Application')
    excel.Visible = False  # 不显示Excel界面
    # 禁用刷新和自动计算（大幅提升速度）
    # excel.ScreenUpdating = False
    # excel.Calculation = win32.constants.xlCalculationManual
    try:
        try:
            title_row = 3
            title_dict = {"PlannedPI":title_row,"Flow SRS ID or GUI SRS ID or Hmi Component Requirement ID":title_row,"Is Valid HMI Scenario?":title_row}
            title_col = {}
            # 打开工作簿
            wb = excel.Workbooks.Open(srs_file)
            # 获取指定工作表
            sheet = wb.Sheets("Integrated SRS")
            # 获取工作表的A1开始已用范围
            last_row = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByRows, SearchDirection=win32.constants.xlPrevious).Row
            last_col = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByColumns, SearchDirection=win32.constants.xlPrevious).Column
            used_range = sheet.Range("A1", sheet.Cells(last_row, last_col))
            for title,row in title_dict.items():
                found_cell = used_range.Rows(row).Cells.Find(What=title, After=sheet.Cells(row, 1), LookIn=win32.constants.xlValues, LookAt=win32.constants.xlWhole)
                if found_cell:
                    title_col[title] = found_cell.Column  # 获取列数字

            if set(title_dict.keys()) == set(title_col.keys()):
                for row in range(title_row+1, used_range.Rows.Count + 1):
                    key_list = []
                    target_cell = used_range.Cells(row,title_col["PlannedPI"])
                    if target_cell.Value and PI_value in target_cell.Value and str(used_range.Cells(row,title_col["Is Valid HMI Scenario?"]).Value).strip() == "Just View check (No scenario)":
                        cell_id = used_range.Cells(row,title_col["Flow SRS ID or GUI SRS ID or Hmi Component Requirement ID"])
                        if cell_id.Value and str(cell_id.Value).strip() != "-":
                            lines = target_cell.Value.split('\n')
                            for index, value in enumerate(lines):
                                if target_cell.Font.Strikethrough != False:
                                    # 获取字符格式对象
                                    chars = target_cell.GetCharacters(Start=sum(len(line)+1 for line in lines[:index])+1, 
                                                        Length=len(lines[index]))
                                    if chars.Font.Strikethrough == False:
                                        key_list.append(str(value).strip())
                                else:
                                    key_list.append(str(value).strip())
                            for key in key_list:
                                if PI_value in key and "Legacy" not in key:
                                    sts_key = str(cell_id.Value).strip()
                                    if sts_key in srs_data:
                                        srs_data[sts_key]["cell"] = f"{srs_data[key]["cell"]},{str(cell_id.Address).replace("$","")}"
                                        if key not in srs_data[sts_key]["PI"]:
                                            srs_data[sts_key]["PI"] = f"{srs_data[key]["PI"]},{key}"
                                    else:
                                        data_dict = {}
                                        data_dict["cell"] = f"{str(cell_id.Address).replace("$","")}"
                                        data_dict["PI"] = key
                                        srs_data[sts_key] = dict(data_dict)
            else:
                print(showwarning(title="warning", message=f"查找[{srs_file}]文件[Integrated SRS]sheet title失败,缺少[{set(title_dict.keys()) - set(title_col.keys())}]title"))
                return
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{srs_file}]文件失败[{e}]"))
            wb.Close(False)
            return
        
        sheet_list = ["ResourceValidation","ResourceValidation(LHD)(old)","ResourceValidation(RHD)(old)"]
        title_row = 3
        title_dict = {}
        title_dict = {"Target PI":title_row,"Hmi Component Requirement ID":title_row}
        try:
            # 打开工作簿
            wb = excel.Workbooks.Open(gtr_file)
            # 获取所有工作表的名称
            sheet_names = [sheet.Name for sheet in wb.Sheets]
            for sheet_name in sheet_list:
                if sheet_name not in sheet_names:
                    print(f"文件[{gtr_file}]中没有找到名为[{sheet_name}]的sheet")
                    continue
                title_col = {}
                # 获取指定工作表
                sheet = wb.Sheets(sheet_name)
                # 获取工作表的已用范围
                last_row = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByRows, SearchDirection=win32.constants.xlPrevious).Row
                last_col = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByColumns, SearchDirection=win32.constants.xlPrevious).Column
                used_range = sheet.Range("A1", sheet.Cells(last_row, last_col))
                for title,row in title_dict.items():
                    found_cell = used_range.Rows(row).Cells.Find(What=title, After=sheet.Cells(row, 1), LookIn=win32.constants.xlValues, LookAt=win32.constants.xlWhole)
                    if found_cell:
                        title_col[title] = found_cell.Column  # 获取列数字
                
                if set(title_dict.keys()) == set(title_col.keys()):
                    for row in range(title_row+1, used_range.Rows.Count + 1):
                        key_list = []
                        target_cell = used_range.Cells(row,title_col["Target PI"])
                        if target_cell.Value and PI_value in target_cell.Value:
                            lines = target_cell.Value.split('\n')
                            for index, value in enumerate(lines):
                                if target_cell.Font.Strikethrough != False:
                                    # 获取字符格式对象
                                    chars = target_cell.GetCharacters(Start=sum(len(line)+1 for line in lines[:index])+1, 
                                                        Length=len(lines[index]))
                                    if chars.Font.Strikethrough == False:
                                        key_list.append(str(value).strip())
                                else:
                                    key_list.append(str(value).strip())
                            for key in key_list:
                                if PI_value in key and "Legacy" not in key:
                                    cell_id = used_range.Cells(row,title_col["Hmi Component Requirement ID"])
                                    cell_addr = str(cell_id.Address).replace("$","")
                                    line_id = cell_id.Value.split('\n')
                                    for id_key in line_id:
                                        id_key = str(id_key).strip()
                                        if id_key in gtr_data:
                                            gtr_data[id_key]["cell"] = f"{gtr_data[id_key]["cell"]},{cell_addr}"
                                            if key not in gtr_data[id_key]["PI"]:
                                                gtr_data[id_key]["PI"] = f"{gtr_data[id_key]["PI"]},{key}"
                                            if sheet_name not in gtr_data[id_key]["sheet"]:
                                                gtr_data[id_key]["sheet"] = f"{gtr_data[id_key]["sheet"]},{sheet_name}"
                                        else:
                                            data_dict = {}
                                            data_dict["cell"] = cell_addr
                                            data_dict["PI"] = key
                                            data_dict["sheet"] = sheet_name
                                            gtr_data[id_key] = dict(data_dict)
                else:
                    print(showwarning(title="warning", message=f"查找[{gtr_file}]文件[{sheet_name}]sheet title失败,缺少[{set(title_dict.keys()) - set(title_col.keys())}]title"))
                    return
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{gtr_file}]文件失败[{e}]"))
            wb.Close(False)
            return
    finally:
        # 确保Excel进程被关闭
        excel.Quit()

    if set(srs_data.keys()) == set(gtr_data.keys()):
        error_list.append(f"[{srs_file}]文件与[{gtr_file}]文件数据完全一致 !!!")
    else:
        for key,value in srs_data.items():
            if key not in gtr_data:
                error_list.append(f"[{srs_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{gtr_file}]文件照合不上")

        # for key,value in gtr_data.items():
        #     if key not in srs_data:
        #         error_list.append(f"[{gtr_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{srs_file}]文件照合不上")
    
    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')
    print(showinfo(title="info", message=f"GTR与SRS的追溯检查 [SUCCESS END] !!!"))

# -------------------------------------------------------------------------------------page_2-------------------------------------------------------------------------------------
# 界面参数
page_2 = ttk.Frame(right_frame)
# notebook.add(page_2, text="")

# 文件路径
def story_file_select_2():
    file_path = filedialog.askopenfilename()
    story_2.config(text=file_path)
story_2 = tk.Message(page_2, width=300, text="")
story_2.place(x=20, y=70, anchor="w")
story_botton_2 = tk.Button(page_2, text="language file", width=15, command=story_file_select_2)
story_botton_2.place(x=350, y=50)

def Ordinary_file_select_2():
    file_path = filedialog.askopenfilename()
    Ordinary_2.config(text=file_path)
Ordinary_2 = tk.Message(page_2, width=300, text="")
Ordinary_2.place(x=20, y=115, anchor="w")
Ordinary_botton_2 = tk.Button(page_2, text="Ordinary file", width=15, command=Ordinary_file_select_2)
Ordinary_botton_2.place(x=350, y=100)

def Popup_file_select_2():
    file_path = filedialog.askopenfilename()
    Popup_2.config(text=file_path)
Popup_2 = tk.Message(page_2, width=300, text="")
Popup_2.place(x=20, y=160, anchor="w")
Popup_botton_2 = tk.Button(page_2, text="Popup file", width=15, command=Popup_file_select_2)
Popup_botton_2.place(x=350, y=150)

def AD_file_select_2():
    file_path = filedialog.askopenfilename()
    AD_2.config(text=file_path)
AD_2 = tk.Message(page_2, width=300, text="")
AD_2.place(x=20, y=215, anchor="w")
AD_botton_2 = tk.Button(page_2, text="AD file", width=15, command=AD_file_select_2)
AD_botton_2.place(x=350, y=200)

def on_entry_pi_in2(event):
    if PI_entry2.get() == "eg:PI26/PI26.1":
        PI_entry2.delete(0, tk.END)  # 清空内容
        PI_entry2.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out2(event):
    if PI_entry2.get() == "":
        PI_entry2.insert(0, "eg:PI26/PI26.1")  # 插入提示字符
        PI_entry2.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label2 = tk.Label(page_2, width=10, text="PI")
PI_label2.place(x=50, y=260, anchor="w")
PI_entry2 = tk.Entry(page_2, width=15, fg="grey")
PI_entry2.insert(0, "eg:PI26/PI26.1")  # 设置初始提示字符
PI_entry2.place(x=100, y=260, anchor="w")
# 绑定事件
PI_entry2.bind("<FocusIn>", on_entry_pi_in2)  # 获取焦点时触发
PI_entry2.bind("<FocusOut>", on_entry_pi_out2)  # 失去焦点时触发

def start_2():
    datacheck_2(story_2["text"], Ordinary_2["text"], Popup_2["text"], AD_2["text"])

start_botton_2 = tk.Button(page_2, text="开始", width=15, command=start_2)
start_botton_2.place(x=350, y=250)

def get_date_dict(sheet, start_row, end_row, PI_value):
    result_dict = {}
    column_b = sheet.Range(sheet.Cells(start_row, 2), sheet.Cells(end_row, 2))  # B1:B{last_row}
    for cell in column_b:
        key_list = []
        if cell.Value:
            lines = cell.Value.split('\n')
            for index, value in enumerate(lines):
                if cell.Font.Strikethrough != False:
                    # 获取字符格式对象
                    chars = cell.GetCharacters(Start=sum(len(line)+1 for line in lines[:index])+1, 
                                        Length=len(lines[index]))
                    if chars.Font.Strikethrough == False:
                        key_list.append(str(value).strip())
                else:
                    key_list.append(str(value).strip())
            for key in key_list:
                if key in result_dict:
                    result_dict[key]["cell"] = f"{result_dict[key]["cell"]},{str(cell.Address).replace("$","")}"
                else:
                    data_dict = {}
                    data_dict["cell"] = f"{str(cell.Address).replace("$","")}"
                    data_dict["PI"] = PI_value
                    result_dict[key] = dict(data_dict)
    return result_dict

def datacheck_2(language_file, Ordinary_file, Popup_file, AD_file):
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass
    PI_value = str(PI_entry2.get()).strip()
    pattern = r'^PI\d+(\.\d)?$'
    PI_match = re.match(pattern, PI_value)
    if PI_match:
        pass
    else:
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不正确"))
        return
        
    error_list = []
    language_data = {}
    Ordinary_data = {}
    Popup_data = {}
    AD_data = {}

    # 启动Excel应用
    excel = win32.gencache.EnsureDispatch('Excel.Application')
    excel.Visible = False  # 不显示Excel界面
    # 禁用刷新和自动计算（大幅提升速度）
    # excel.ScreenUpdating = False
    # excel.Calculation = win32.constants.xlCalculationManual
    try:
        try:
            title_row = 2
            title_dict = {"Tested feature":title_row,"Tested PI":title_row,"Text ID":title_row}
            title_col = {}
            # 打开工作簿
            wb = excel.Workbooks.Open(language_file)
            # 获取指定工作表
            sheet = wb.Sheets("Text_Change_Chart")
            # 获取工作表的A1开始已用范围
            last_row = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByRows, SearchDirection=win32.constants.xlPrevious).Row
            last_col = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByColumns, SearchDirection=win32.constants.xlPrevious).Column
            used_range = sheet.Range("A1", sheet.Cells(last_row, last_col))
            for title,row in title_dict.items():
                found_cell = used_range.Rows(row).Cells.Find(What=title, After=sheet.Cells(row, 1), LookIn=win32.constants.xlValues, LookAt=win32.constants.xlWhole)
                if found_cell:
                    title_col[title] = found_cell.Column  # 获取列数字

            if set(title_dict.keys()) == set(title_col.keys()):
                for row in range(title_row+1, used_range.Rows.Count + 1):
                    key_list = []
                    target_cell = used_range.Cells(row,title_col["Tested PI"])
                    if target_cell.Value and PI_value in target_cell.Value:
                        lines = target_cell.Value.split('\n')
                        for index, value in enumerate(lines):
                            if target_cell.Font.Strikethrough != False:
                                # 获取字符格式对象
                                chars = target_cell.GetCharacters(Start=sum(len(line)+1 for line in lines[:index])+1, 
                                                    Length=len(lines[index]))
                                if chars.Font.Strikethrough == False:
                                    key_list.append(str(value).strip())
                            else:
                                key_list.append(str(value).strip())
                        for key in key_list:
                            if PI_value in key and "Legacy" not in key:
                                cell_id = used_range.Cells(row,title_col["Text ID"])
                                data_dict = {}
                                data_dict["cell"] = f"{str(cell_id.Address).replace("$","")}"
                                data_dict["PI"] = key
                                data_dict["feature"] = str(used_range.Cells(row,title_col["Tested feature"]).Value).strip()
                                language_data[str(cell_id.Value).strip()] = dict(data_dict)
            else:
                print(showwarning(title="warning", message=f"查找[{language_file}]文件[Integrated SRS]sheet title失败,缺少[{set(title_dict.keys()) - set(title_col.keys())}]title"))
                return
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{language_file}]文件失败[{e}]"))
            wb.Close(False)
            return
        
        try:
            if "25" in PI_value:
                title_row = 3
                title_dict = {}
                title_dict = {"Target TextID":title_row,"PI ID":title_row}
                title_col = {}
                # 打开工作簿
                wb = excel.Workbooks.Open(Ordinary_file)
                # 获取指定工作表
                sheet = wb.Sheets("TextValidation")
                # 获取B列所有非空单元格（动态范围）
                last_row = sheet.Cells(sheet.Rows.Count, 2).End(win32.constants.xlUp).Row  # B列最后非空行
                Ordinary_data = get_date_dict(sheet, 4, last_row, PI_value)
                wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{Ordinary_file}]文件失败[{e}]"))
            wb.Close(False)
            return
            
        try:
            title_row = 3
            title_dict = {}
            title_dict = {"Target TextID":title_row,"PI ID":title_row}
            title_col = {}
            if "23" in PI_value:
                start_row = 161
                end_row = 1146
            elif "24" in PI_value:
                start_row = 1147
                end_row = 1232
            elif "25" in PI_value:
                start_row = 1233
                end_row = 2758
            else:
                print(showwarning(title="warning", message=f"读取[{Popup_file}]文件失败[{PI_value}]错误"))
                return

            # 打开工作簿
            wb = excel.Workbooks.Open(Popup_file)
            # 获取指定工作表
            sheet = wb.Sheets("TextValidation")
            Popup_data = get_date_dict(sheet, start_row, end_row, PI_value)
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{Popup_file}]文件失败[{e}]"))
            wb.Close(False)
            return
            
        try:
            title_row = 3
            title_dict = {}
            title_dict = {"Target TextID":title_row,"PI ID":title_row}
            title_col = {}
            if "23" in PI_value:
                start_row = 4
                end_row = 7
            elif "24" in PI_value:
                start_row = 8
                end_row = 11
            elif "25" in PI_value:
                start_row = 12
                end_row = 77
            else:
                print(showwarning(title="warning", message=f"读取[{AD_file}]文件失败[{PI_value}]错误"))
                return

            # 打开工作簿
            wb = excel.Workbooks.Open(AD_file)
            # 获取指定工作表
            sheet = wb.Sheets("TextValidation")
            AD_data = get_date_dict(sheet, start_row, end_row, PI_value)
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{AD_file}]文件失败[{e}]"))
            wb.Close(False)
            return
    finally:
        # 确保Excel进程被关闭
        excel.Quit()

    for key,value in language_data.items():
        if "Ordinary" in value["feature"]:
            if key not in Ordinary_data:
                error_list.append(f"[{language_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{Ordinary_file}]文件照合不上")
        elif "Popup" in value["feature"]:
            if key not in Popup_data:
                error_list.append(f"[{language_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{Popup_file}]文件照合不上")
        elif "AD" in value["feature"]:
            if key not in AD_data:
                error_list.append(f"[{language_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{AD_file}]文件照合不上")
        else:
            error_list.append(f"[{language_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[其他]文件照合不上 !!!")
    
    for key,value in Ordinary_data.items():
        if key not in language_data:
            error_list.append(f"[{Ordinary_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{language_file}]文件照合不上")
        else:
            if "Ordinary" not in language_data[key]["feature"]:
                error_list.append(f"[{Ordinary_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{language_file}]文件照合不上")
                
    for key,value in Popup_data.items():
        if key not in language_data:
            error_list.append(f"[{Popup_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{language_file}]文件照合不上")
        else:
            if "Popup" not in language_data[key]["feature"]:
                error_list.append(f"[{Popup_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{language_file}]文件照合不上")
                
    for key,value in AD_data.items():
        if key not in language_data:
            error_list.append(f"[{AD_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{language_file}]文件照合不上")
        else:
            if "AD" not in language_data[key]["feature"]:
                error_list.append(f"[{AD_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{language_file}]文件照合不上")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')
    print(showinfo(title="info", message=f"GTR与text文言追溯检查[SUCCESS END] !!!"))

# -------------------------------------------------------------------------------------page_3-------------------------------------------------------------------------------------
# 界面参数
page_3 = ttk.Frame(right_frame)

# 文件路径
def story_file_select_3():
    file_path = filedialog.askopenfilename()
    story_3.config(text=file_path)
story_3 = tk.Message(page_3, width=300, text="")
story_3.place(x=20, y=70, anchor="w")
story_botton_3 = tk.Button(page_3, text="SRS file", width=15, command=story_file_select_3)
story_botton_3.place(x=350, y=50)

def C3IM_file_select_3():
    file_path = filedialog.askopenfilename()
    C3IM_3.config(text=file_path)
C3IM_3 = tk.Message(page_3, width=300, text="")
C3IM_3.place(x=20, y=120, anchor="w")
C3IM_botton_3 = tk.Button(page_3, text="STR file", width=15, command=C3IM_file_select_3)
C3IM_botton_3.place(x=350, y=100)

def on_entry_pi_in3(event):
    if PI_entry3.get() == "eg:PI26/PI26.1":
        PI_entry3.delete(0, tk.END)  # 清空内容
        PI_entry3.config(fg="black")  # 设置文本颜色为黑色

def on_entry_pi_out3(event):
    if PI_entry3.get() == "":
        PI_entry3.insert(0, "eg:PI26/PI26.1")  # 插入提示字符
        PI_entry3.config(fg="grey")  # 设置文本颜色为灰色
# PI
PI_label3 = tk.Label(page_3, width=10, text="PI")
PI_label3.place(x=50, y=160, anchor="w")
PI_entry3 = tk.Entry(page_3, width=15, fg="grey")
PI_entry3.insert(0, "eg:PI26/PI26.1")  # 设置初始提示字符
PI_entry3.place(x=100, y=160, anchor="w")
# 绑定事件
PI_entry3.bind("<FocusIn>", on_entry_pi_in3)  # 获取焦点时触发
PI_entry3.bind("<FocusOut>", on_entry_pi_out3)  # 失去焦点时触发

def start_3():
    datacheck_3(story_3["text"], C3IM_3["text"])

start_botton_3 = tk.Button(page_3, text="开始", width=15, command=start_3)
start_botton_3.place(x=350, y=150)

def datacheck_3(srs_file, str_file):
    try:
        os.remove(str(os.path.dirname(app_path())) + "\\" + "error.txt")
    except:
        pass

    PI_value = str(PI_entry3.get()).strip()
    pattern = r'^PI\d+(\.\d)?$'
    PI_match = re.match(pattern, PI_value)
    if PI_match:
        pass
    else:
        print(showwarning(title="warning", message=f"输入PI=[{PI_value}]数据不正确"))
        return

    error_list = []
    srs_data = {}
    gtr_data = {}
    # 启动Excel应用
    excel = win32.gencache.EnsureDispatch('Excel.Application')
    excel.Visible = False  # 不显示Excel界面
    # 禁用刷新和自动计算（大幅提升速度）
    # excel.ScreenUpdating = False
    # excel.Calculation = win32.constants.xlCalculationManual
    try:
        try:
            title_row = 3
            title_dict = {"PlannedPI":title_row,"Integrated SRS ID":title_row}
            title_col = {}
            # 打开工作簿
            wb = excel.Workbooks.Open(srs_file)
            # 遍历所有工作表
            # for sheet in wb.Sheets:
            # 获取指定工作表
            sheet = wb.Sheets("Integrated SRS")
            # 获取工作表的已用范围
            last_row = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByRows, SearchDirection=win32.constants.xlPrevious).Row
            last_col = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByColumns, SearchDirection=win32.constants.xlPrevious).Column
            used_range = sheet.Range("A1", sheet.Cells(last_row, last_col))
            for title,row in title_dict.items():
                found_cell = used_range.Rows(row).Cells.Find(What=title, After=sheet.Cells(row, 1), LookIn=win32.constants.xlValues, LookAt=win32.constants.xlWhole)
                if found_cell:
                    title_col[title] = found_cell.Column  # 获取列数字

            if set(title_dict.keys()) == set(title_col.keys()):
                for row in range(title_row+1, used_range.Rows.Count + 1):
                    key_list = []
                    target_cell = used_range.Cells(row,title_col["PlannedPI"])
                    if target_cell.Value and PI_value in target_cell.Value:
                        lines = target_cell.Value.split('\n')
                        for index, value in enumerate(lines):
                            if target_cell.Font.Strikethrough != False:
                                # 获取字符格式对象
                                chars = target_cell.GetCharacters(Start=sum(len(line)+1 for line in lines[:index])+1, 
                                                    Length=len(lines[index]))
                                if chars.Font.Strikethrough == False:
                                    key_list.append(str(value).strip())
                            else:
                                key_list.append(str(value).strip())
                        for key in key_list:
                            if PI_value in key and "Legacy" not in key:
                                data_dict = {}
                                cell_id = used_range.Cells(row,title_col["Integrated SRS ID"])
                                data_dict["cell"] = f"{str(cell_id.Address).replace("$","")}"
                                data_dict["PI"] = key
                                srs_data[str(cell_id.Value).strip()] = dict(data_dict)
            else:
                print(showwarning(title="warning", message=f"查找[{srs_file}]文件[Integrated SRS]sheet title失败,缺少[{set(title_dict.keys()) - set(title_col.keys())}]title"))
                return
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{srs_file}]文件失败[{e}]"))
            wb.Close(False)
            return
        
        sheet_list = ["Software Scenario Test","Software Unit Verification"]
        try:
            # 打开工作簿
            wb = excel.Workbooks.Open(str_file)
            # 获取所有工作表的名称
            sheet_names = [sheet.Name for sheet in wb.Sheets]
            for sheet_name in sheet_list:
                if sheet_name not in sheet_names:
                    print(f"文件[{str_file}]中没有找到名为[{sheet_name}]的sheet")
                    continue
                if sheet_name == "Software Scenario Test":
                    title_row = 10
                elif sheet_name == "Software Unit Verification":
                    title_row = 2
                else:
                    title_row = 10
                title_dict = {}
                title_dict = {"Planned PI":title_row,"Integrated SRS ID":title_row}
                title_col = {}
                # 获取指定工作表
                sheet = wb.Sheets(sheet_name)
                last_row = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByRows, SearchDirection=win32.constants.xlPrevious).Row
                last_col = sheet.Cells.Find("*", SearchOrder=win32.constants.xlByColumns, SearchDirection=win32.constants.xlPrevious).Column
                used_range = sheet.Range("A1", sheet.Cells(last_row, last_col))
                for title,row in title_dict.items():
                    found_cell = used_range.Rows(row).Cells.Find(What=title, After=sheet.Cells(row, 1), LookIn=win32.constants.xlValues, LookAt=win32.constants.xlWhole)
                    if found_cell:
                        title_col[title] = found_cell.Column  # 获取列数字
                
                if set(title_dict.keys()) == set(title_col.keys()):
                    for row in range(title_row+1, used_range.Rows.Count + 1):
                        key_list = []
                        target_cell = used_range.Cells(row,title_col["Planned PI"])
                        if target_cell.Value and PI_value in target_cell.Value:
                            lines = target_cell.Value.split('\n')
                            for index, value in enumerate(lines):
                                if target_cell.Font.Strikethrough != False:
                                    # 获取字符格式对象
                                    chars = target_cell.GetCharacters(Start=sum(len(line)+1 for line in lines[:index])+1, 
                                                        Length=len(lines[index]))
                                    if chars.Font.Strikethrough == False:
                                        key_list.append(str(value).strip())
                                else:
                                    key_list.append(str(value).strip())
                            for key in key_list:
                                if PI_value in key and "Legacy" not in key:
                                    cell_id = used_range.Cells(row,title_col["Integrated SRS ID"])
                                    cell_addr = str(cell_id.Address).replace("$","")
                                    line_id = cell_id.Value.split('\n')
                                    for id_key in line_id:
                                        id_key = str(id_key).strip()
                                        if id_key in gtr_data:
                                            gtr_data[id_key]["cell"] = f"{gtr_data[id_key]["cell"]},{cell_addr}"
                                            if key not in gtr_data[id_key]["PI"]:
                                                gtr_data[id_key]["PI"] = f"{gtr_data[id_key]["PI"]},{key}"
                                            if sheet_name not in gtr_data[id_key]["sheet"]:
                                                gtr_data[id_key]["sheet"] = f"{gtr_data[id_key]["sheet"]},{sheet_name}"
                                        else:
                                            data_dict = {}
                                            data_dict["cell"] = cell_addr
                                            data_dict["PI"] = key
                                            data_dict["sheet"] = sheet_name
                                            gtr_data[id_key] = dict(data_dict)
                else:
                    print(showwarning(title="warning", message=f"查找[{str_file}]文件[{sheet_name}]sheet title失败,缺少[{set(title_dict.keys()) - set(title_col.keys())}]title"))
                    return
            wb.Close(False)
        except Exception as e:
            print(showwarning(title="warning", message=f"读取[{str_file}]文件失败[{e}]"))
            wb.Close(False)
            return
    finally:
        # 确保Excel进程被关闭
        excel.Quit()
    
    if set(srs_data.keys()) == set(gtr_data.keys()):
        error_list.append(f"[{srs_file}]文件与[{str_file}]文件数据完全一致 !!!")
    else:
        for key,value in srs_data.items():
            if key not in gtr_data:
                error_list.append(f"[{srs_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{str_file}]文件照合不上")

        for key,value in gtr_data.items():
            if key not in srs_data:
                error_list.append(f"[{str_file}]文档中,[{value["PI"]}],[{value["cell"]}]单元格[{key}]数据与[{srs_file}]文件照合不上")

    with open(str(os.path.dirname(app_path())) + "\\error.txt", 'a', encoding='utf-8') as f:
        for error in error_list:
            f.write(str(error) + '\n')
    print(showinfo(title="info", message=f"GTR与text文言追溯检查[SUCCESS END] !!!"))
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 添加一些内容到页面
ttk.Label(page_1, text="GTR与SRS的追溯检查").pack(pady=5)
ttk.Label(page_2, text="GTR与text文言追溯检查").pack(pady=5)
ttk.Label(page_3, text="STR与SRS的追溯检查").pack(pady=5)
# 在左侧 Frame 中添加按钮,用于切换页面
def show_page(page):
    for p in [page_1, page_2, page_3]:
        p.pack_forget()  # 隐藏所有页面
    page.pack(fill=tk.BOTH, expand=True)  # 显示当前页面

button_1 = ttk.Button(left_frame, text="GTR与SRS的追溯检查", command=lambda: show_page(page_1))
button_1.pack(pady=10, fill=tk.X)
button_2 = ttk.Button(left_frame, text="GTR与text文言追溯检查", command=lambda: show_page(page_2))
button_2.pack(pady=10, fill=tk.X)
button_3 = ttk.Button(left_frame, text="STR与SRS的追溯检查", command=lambda: show_page(page_3))
button_3.pack(pady=10, fill=tk.X)

# 默认显示第一个页面
show_page(page_1)
# # 将Notebook放入根窗口
# notebook.pack(expand=1, fill="both")

# 回调函数
def refresh():
    window.after(100, refresh)

# 注册第一次回调函数
window.after(100, refresh)

window.mainloop()